import { CJDBUtil } from '../db/CJDBUtil'
import "reflect-metadata";
import { AnnotationEnum } from '../annotation/AnnotationEnum';
import { Id } from '../annotation/Id';
import { OperatorType } from '../db/OperatorType';
import { Condition } from '../db/Condition';
import { TableStruct, TableStructCache } from '../db/TableStructCache';
import { ObjectUtil } from '../utils/ObjectUtil';

const TAG = "CJBaseModel"

export abstract class CJBaseModel {
  // protected cjIdName?: string
  // protected cjTableName?: string

  // @Id()
  // id: number | string

  // static tableName: string
  // static objects = {
  //   get: () => {
  //     console.log(TAG, JSON.stringify(CJBaseModel.prototype))
  //     console.log(TAG,)
  //   },
  //   all: () => {
  //
  //   },
  //   filter: () => {
  //
  //   },
  //   delete: () => {
  //
  //   }
  // }

  static query() {

  }

  delete(): Promise<number> {
    if (!this.getId()) {
      throw new Error('id can not exist！');
    }
    return CJDBUtil.delete(this.getClassName(), [
      new Condition(this.getColumnIdName(), OperatorType.EQUAL_TO, this.getId())
    ])
  }

  save(): Promise<number> {
    if (!this.getId()) {
      return CJDBUtil.save(this)
    } else {
      // 判断ID是否自增长
      if (TableStructCache.idMaps.get(this.getClassName())?.autoincrement) {
        return this.update()
      } else {
       return  CJDBUtil.getById(this.getClassName(), this.getId())
          .then(res => res ? this.update() : CJDBUtil.save(this))
      }
    }
  }

  update(): Promise<number> {
    if (!this.getId()) {
      throw new Error('id can not exist！');
    }
[["id","=","33"]]
    let values = ObjectUtil.clone(this)
    // delete values.id
    return CJDBUtil.update(this.getClassName(), values, [
      new Condition(this.getColumnIdName(), OperatorType.EQUAL_TO, this.getId())
    ])
  }

  /**
   * 注意：当类使用Observed修饰时需要重写
   * @returns
   */
  getClassName() {
    return this.constructor.name
  }

  getId(): number | string | undefined {
    return this[this.getIdName()]
  }

  getIdName(): string | undefined {
    // if (this.cjIdName) {
    //   return this.cjIdName
    // } else {
    //   if (TableStructCache.structMaps.has(this.getClassName())) {
    //     let structs: Array<TableStruct> = TableStructCache.structMaps.get(this.getClassName())
    //     for (let i = 0; i < structs.length; i++) {
    //       if (structs[i].isId) {
    //         this.cjIdName = structs[i].name
    //         return this.cjIdName
    //       }
    //     }
    //   }
    // }
    // return "_id"
    return TableStructCache.idMaps.get(this.getClassName()).idName
  }

  getColumnIdName() {
    return TableStructCache.idMaps.get(this.getClassName()).idColumnName
  }
}